#include <thread>
#include <iostream>
#include <mutex>

using std::cout;
using std::endl;

struct Complex{
    std::mutex mutex;
    int i;
    Complex():i(0) {}

    void mul(int x)
    {
        std::lock_guard<std::mutex> lock(mutex);
        i*=x;
    }

    void div(int x)
    {
        std::lock_guard<std::mutex> lock(mutex);
        i /= x;
    }

    void both(int x, int y)
    {
        std::lock_guard<std::mutex> lock(mutex);
        mul(x);
        div(y);
    }
};



void fun()
{
    Complex complex;
    complex.both(32, 23);
}

struct Complex_recur{
    std::recursive_mutex mutex; //同一线程可以多次获取同一互斥锁，不会发生死锁
    int i;
    Complex_recur():i(0) {}

    void mul(int x)
    {
        std::lock_guard<std::recursive_mutex> lock(mutex);
        i*=x;
    }

    void div(int x)
    {
        std::lock_guard<std::recursive_mutex> lock(mutex);
        i /= x;
    }

    void both(int x, int y)
    {
        std::lock_guard<std::recursive_mutex> lock(mutex);
        mul(x);
        div(y);
        cout << "end" << std::endl;
    }
};

void fun_recur()
{
    Complex_recur complex;
    for(int i = 0; i < 10000; ++i)
        complex.both(32, 23);
}


int main(void)
{
    std::thread t(fun_recur);
    t.join();
    return 0;
}
